package com.study.drascale;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.util.concurrent.DelayQueue;
import java.util.concurrent.Delayed;
import java.util.concurrent.TimeUnit;

import android.app.Activity;
import android.content.Context;
import android.graphics.Matrix;
import android.os.AsyncTask;
import android.os.Bundle;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnTouchListener;
import android.widget.ImageView;

public class MainActivity extends Activity {
    private final static String TAG = "TouchScale";
    private final long mPreDelay = 250; /* 前延时，延时获取mOriginArea */
    private final long mPostDelay = 150; /* 后延时，放手时丢弃DelayQueue中未取的值，用来保存当前的放大状态 */
    private final long mInterval = 10; /* 间隔，防止运行太快影响性能 */

    protected Context mContext;
    private ImageView mImageView; /* 图片所在 */

    protected static boolean mUsing = false; /* 为了开关UpdateViewTask中的循环，true为打开循环，false关闭循环，结束task */
    private static float mOriginArea; /* 记录手指的原始面积值 */
    private long mOriginTime; /* 记录原始面积值获取的时间点 */
    private Matrix mOrgMatrix; /* 记录原始的图片矩阵 */
    private Matrix mOrgMatrix0; /* 记录原始的图片矩阵 */
    private UpdateViewTask mUVT; /* 更新显示的AsyncTask */
    /* 用DelayQueue来实现后延时mPostDelay，ACTION_UP时未来得及取出的值将直接丢弃 */
    protected DelayQueue<ScaleInQueue> mDelayQueue = new DelayQueue<ScaleInQueue>();

    /* 拟合scale和time */
    private FileOutputStream out = null;
    private StringBuffer sb;
    
    /*生成文件个数*/
    private int fileCount = 0;

    public FileOutputStream FileInit(int fileCount) throws IOException {
        String fileDir = getString(R.string._sdcard_mtklog_area_touch_txt);
        String fileName = "ScaleTime"+fileCount+".txt";
        
        File file = new File(fileDir+fileName);
        if (!file.exists())
            file.createNewFile();

        FileOutputStream out = new FileOutputStream(file, true);
        return out;
    }

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        mImageView = (ImageView) findViewById(R.id.img);
        mImageView.setOnTouchListener(new TounchListener());
        mOrgMatrix = mImageView.getImageMatrix();
        mOrgMatrix0 = mImageView.getImageMatrix();
        mContext = this;
        Log.d(TAG, "onCreate is over.");
    }

    private class TounchListener implements OnTouchListener {
        /*记录双击次数*/
        int count = 0;
        int firClick = 0;
        int secClick = 0;

        public boolean onTouch(View v, MotionEvent event) {

            if (MotionEvent.ACTION_DOWN == event.getAction()) {
                count++;
                if (count == 1) {
                    firClick = (int) System.currentTimeMillis();

                } else if (count == 2) {
                    secClick = (int) System.currentTimeMillis();
                    if ((secClick - firClick < 1000)
                            && (mOrgMatrix != mOrgMatrix0)) {
                        /*双击事件 ，恢复原始面积*/
                        Log.d(TAG, "on double click");
                        Matrix matrix = new Matrix(mOrgMatrix0);
                        mImageView.setImageMatrix(matrix);
                    }
                    count = 0;
                    firClick = 0;
                    secClick = 0;
                }
            }

            Log.i(TAG, "action=" + MotionEvent.actionToString(event.getAction()));
            switch (event.getAction() & MotionEvent.ACTION_MASK) {
            case MotionEvent.ACTION_DOWN:
                mUsing = true; /* 暂时放这里 */
                mUVT = new UpdateViewTask(event);
                /* 执行UpdateViewTask */
                mUVT.execute(new Void[0]);
                break;

            case MotionEvent.ACTION_UP:
                mUsing = false;
                // mUVT.cancel(true);
                break;

            case MotionEvent.ACTION_MOVE:
                if (mOriginArea == 0) { /* 仍然在执行mPreDelay */
                    Log.i(TAG, "mOriginArea=" + mOriginArea);
                    return false;
                } else if (mOriginArea < 0) { /* 说明mPreDelay已经执行完毕 */
                    /* 获取初始面积值和时间 */
                    mOriginArea = event.getAxisValue(48)
                            * event.getAxisValue(48);
                    mOriginTime = System.currentTimeMillis();
                    Log.i(TAG, "mOriginArea=" + mOriginArea);
                    /* 给DelayQueue放入第一个元素，初始scale一定为1，时间为mOriginTime */
                    ScaleInQueue siq = new ScaleInQueue(1.0f, mOriginTime);
                    mDelayQueue.put(siq);
                    Log.d(TAG, "put 1 in DelayQueue.");
                    return true;
                } else { /* 即mOriginArea < 0，把获取的面积值及其时间，塞入DelayQueue */
                    float currentArea = event.getAxisValue(48) * event.getAxisValue(48);
                    float scale = trans(currentArea);
                    ScaleInQueue siq = new ScaleInQueue(scale, System.currentTimeMillis());
                    mDelayQueue.put(siq);
                    Log.d(TAG, "put " + scale + " in DelayQueue.");
                }
                break;
            }
            return true;
        }

    }

    private class ScaleInQueue implements Delayed {
        protected float scale;
        protected long time;

        public ScaleInQueue(float scale, long time) {
            this.scale = scale;
            this.time = time;
        }

        public int compareTo(Delayed o) {
            /* 时间靠后的排前面 */
            ScaleInQueue other = (ScaleInQueue) o;
            Log.i(TAG, "In compareTo " + (time - other.time));
            if (time < other.time) {
                return -1;
            } else if (time > other.time) {
                return 1;
            } else {
                return 0;
            }
        }

        public long getDelay(TimeUnit unit) {
            /* 实现mPostDelay的关键 */
            return unit.convert(time + mPostDelay - System.currentTimeMillis(),
                    TimeUnit.MILLISECONDS);
        }
    }

    private class UpdateViewTask extends AsyncTask<Void, ScaleInQueue, Void> {
        private MotionEvent event;
        public UpdateViewTask(MotionEvent event){
            this.event = event;
        }
        @Override
        protected void onPreExecute() {
            /* 实现mPreDelay的关键 */
            delay(mPreDelay);

            /*创建文档记录数据*/
            try {
                out = FileInit(fileCount);
                fileCount++;
            } catch (IOException e) {
                e.printStackTrace();
            }
            
            mOriginArea = -1;
            Log.d(TAG, "In onPreExecute, delay is over.");
        }

        @Override
        protected Void doInBackground(Void... unused) {
            /* 从DelayQueue里去值，取到则执行更新操作，否则间隔mInterval毫秒再取 */
            while (mUsing) {
                if (mOriginArea > 0) {
                    ScaleInQueue siq = mDelayQueue.poll();
                    if (siq != null) {
                        /* 调用onProgressUpdate */
                        publishProgress(siq);
                    }
                }
                delay(mInterval);
            }
            return null;
        }

        @Override
        protected void onProgressUpdate(ScaleInQueue... siq) {
            Log.i(TAG, "In onProgressUpdate, scale is " + siq[0].scale);
            /* 更新图片大小 */
            Matrix matrix = new Matrix(mOrgMatrix);
            //matrix.postScale(siq[0].scale, siq[0].scale);
            matrix.setScale(siq[0].scale, siq[0].scale, event.getAxisValue(0), event.getAxisValue(1));
            mImageView.setImageMatrix(matrix);
            /* 打印time和scale */
            sb = new StringBuffer();

            /*write the test data to sdcard file*/
            sb.append(siq[0].scale + "     " + (siq[0].time - mOriginTime));
            sb.append("\n");
            Log.i(TAG, "scale=" + siq[0].scale + "   ,time=" + (siq[0].time - mOriginTime));

            try {
                out.write(sb.toString().getBytes("utf-8"));
            } catch (UnsupportedEncodingException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            }

        }

        @Override
        protected void onPostExecute(Void unused) {
            /* 清空原始面积值、时间 */
            mOriginArea = 0;
            mOriginTime = 0;
            /* 清空DelayQueue，丢弃其中未执行的值，mPostDelay的关键 */
            mDelayQueue.clear();
            // mOrgMatrix = mImageView.getImageMatrix();
            
            /*关闭文档，结束记录*/
            try {
                out.close();
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }

        /**
         * @param delayTime
         *            延时时间，单位毫秒（ms）
         */
        private void delay(long delayTime) {
            try {
                if (delayTime > 100) {
                    Log.i(TAG, "delay " + delayTime + " ms");
                }
                Thread.sleep(delayTime);
            } catch (InterruptedException e) {
                Log.e(TAG, "InterruptedException", e);
            } finally {
            }
        }
    };

    public float trans(float currentArea) {
        /* 暂时先用线性函数 */
        return currentArea / mOriginArea;
    }

}
